package com.settlement.system.model.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.settlement.system.common.base.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 标准账单
 * </p>
 *
 * @author huangrensen
 * @since 2023-08-05
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SysBill extends BaseEntity {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id")
    private String id;

    /**
     * 唯一标识
     */
    private String pId;

    /**
     * 对账系统店铺编码
     */
    private String billSystemStoreCode;

    /**
     * 对账系统平台编码
     */
    private String billSystemPlatformCode;

    /**
     * 电商平台店铺编码
     */
    private String commercePlatformStoreCode;

    /**
     * 电商平台店铺名称
     */
    private String commercePlatformStoreName;

    /**
     * 财务系统店铺编码
     */
    private String billSysStore;

    /**
     * 财务系统店铺名称
     */
    private String billSysStoreName;

    /**
     * 电商平台店铺编码
     */
    private String thirdSourceCode;

    /**
     * 电商平台店铺名称
     */
    private String thirdSourceName;

    /**
     * 关联单号
     */
    private String linkNo;

    /**
     * 统一账单ID
     */
    private String sysBillId;

    /**
     * 汇总ID
     */
    private String summaryId;

    /**
     * 出账日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime billDate;

    /**
     * 业务日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime businessDate;

    /**
     * 账单金额
     */
    private BigDecimal billAmount = BigDecimal.ZERO;

    /**
     * 电商平台账单项目
     */
    private String originalBillProject;

    /**
     * 记账项目
     */
    private String billProject;

    /**
     * 一级科目编码
     */
    private String firstCode;

    /**
     * 一级科目名称
     */
    private String firstName;

    /**
     * 末级科目编码
     */
    private String lastCode;

    /**
     * 末级科目名称
     */
    private String lastName;

    /**
     * 一级科目编码
     */
    private String otherFirstCode;

    /**
     * 一级科目名称
     */
    private String otherFirstName;

    /**
     * 末级科目编码
     */
    private String otherLastCode;

    /**
     * 末级科目名称
     */
    private String otherLastName;

    /**
     * 辅助项配置
     */
    private String accessory;

    /**
     * 对方辅助项配置
     */
    private String otherAccessory;

    /**
     * 入账主体编码
     */
    private String companyCode;

    /**
     * 会计期间
     */
    private String sysBillDate;

    /**
     * 是否分摊
     */
    private String apportionment;

    /**
     * 票前票后
     */
    private String invoice;

    /**
     * 稽核标识
     */
    private String audit;

    /**
     * 是否参与记账
     */
    private String accounting;
    /**
     * 记账状态
     */
    private String status;
    /**
     * 供应商名称
     */
    private String carrier;

    /**
     * 借贷方向
     */
    private String borrowing;

    /**
     * 税额
     */
    private BigDecimal taxAmount = BigDecimal.ZERO;

    /**
     * 创建人ID
     */
    private Long createBy;

    /**
     * 修改人ID
     */
    private Long updateBy;

    /**
     * 所属角色
     */
    private String belongRole;

    /**
     * 店铺ID
     */
    private Long storeId;

    @TableField(exist = false)
    private String tableName;

    // 为了汇总而冗余的字段
    @TableField(exist = false)
    private String accessoryText;

    // 结算单类型
    private String settlementType;

    /**
     * 核销单ID
     */
    private String auditId;
    /**
     * 归档核销单ID
     */
    private String fileAuditId;

    /**
     * 删除标识  0-未删除  1-已删除
     */
    private int delete = 0;

    public static boolean isDate(String field){
        return "billMonth,businessDate,billDate".contains(field);
    }
    public static boolean isDecimal(String field){
        return "billAmount".contains(field);
    }

    private static boolean compareDate(LocalDateTime date1, LocalDateTime date2) {
        if (date1 == null && date2 == null) {
            return true;
        }
        if (date1 != null && date2 == null) {
            return false;
        }
        return date1 != null && date1.equals(date2);
    }

    private static boolean compareBigDecimal(BigDecimal value1, BigDecimal value2) {
        if (value1 == null && value2 == null) {
            return true;
        }
        if (Objects.isNull(value2)) {
            value2 = BigDecimal.ZERO;
        }
        return value1 != null && value1.compareTo(value2) == 0;
    }
    public static Map<String, String> getColumnMap() {
        Map<String, String> columnMap = new HashMap<>();
        columnMap.put("关联单号", "linkNo");
        columnMap.put("电商平台账单项目", "originalBillProject");
        columnMap.put("账单金额", "billAmount");
        columnMap.put("结算单类型", "settlementType");
        columnMap.put("业务日期", "businessDate");
        columnMap.put("出账日期", "billDate");
        columnMap.put("唯一标识", "pId");
        return columnMap;
    }

    public boolean isSameBill(SysBill bill){
        return Objects.equals(linkNo, bill.getLinkNo()) &&
                Objects.equals(originalBillProject, bill.getOriginalBillProject()) &&
                compareDate(billDate, bill.getBillDate()) &&
                Objects.equals(pId, bill.getPId());
    }

    public boolean isSameBillProjectBill(SysBill bill){
        return Objects.equals(linkNo, bill.getLinkNo()) &&
                Objects.equals(originalBillProject, bill.getOriginalBillProject());
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        SysBill sysBill = (SysBill) o;
        return Objects.equals(billSystemStoreCode, sysBill.billSystemStoreCode) && Objects.equals(billSystemPlatformCode, sysBill.billSystemPlatformCode) && Objects.equals(commercePlatformStoreCode, sysBill.commercePlatformStoreCode) && Objects.equals(billSysStore, sysBill.billSysStore) && Objects.equals(thirdSourceCode, sysBill.thirdSourceCode) && Objects.equals(linkNo, sysBill.linkNo) && compareDate(billDate, sysBill.billDate) && compareDate(businessDate, sysBill.businessDate) && compareBigDecimal(billAmount, sysBill.billAmount) && Objects.equals(originalBillProject, sysBill.originalBillProject) && Objects.equals(billProject, sysBill.billProject) && Objects.equals(firstCode, sysBill.firstCode) && Objects.equals(lastCode, sysBill.lastCode) && Objects.equals(otherFirstCode, sysBill.otherFirstCode) && Objects.equals(otherLastCode, sysBill.otherLastCode) && Objects.equals(companyCode, sysBill.companyCode) && Objects.equals(sysBillDate, sysBill.sysBillDate) && Objects.equals(apportionment, sysBill.apportionment) && Objects.equals(invoice, sysBill.invoice) && Objects.equals(audit, sysBill.audit) && Objects.equals(accounting, sysBill.accounting) && Objects.equals(status, sysBill.status) && Objects.equals(carrier, sysBill.carrier) && Objects.equals(borrowing, sysBill.borrowing) && compareBigDecimal(taxAmount, sysBill.taxAmount) && Objects.equals(storeId, sysBill.storeId) && Objects.equals(settlementType, sysBill.settlementType);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), billSystemStoreCode, billSystemPlatformCode, commercePlatformStoreCode, billSysStore, thirdSourceCode, linkNo, billDate, businessDate, billAmount, originalBillProject, billProject, firstCode, lastCode, otherFirstCode, otherLastCode, companyCode, sysBillDate, apportionment, invoice, audit, accounting, status, carrier, borrowing, taxAmount, storeId, settlementType);
    }
}
